package com.example.sens.service.impl;

import com.baomidou.mybatisplus.plugins.Page;
import com.example.sens.entity.*;
import com.example.sens.mapper.*;
import com.example.sens.service.ThresholdService;
import com.example.sens.utils.Response;
import com.example.sens.utils.UUIDUtil;
import com.example.sens.vo.ThresholdVo;
import com.example.sens.vo.UserThresholdSaveCustomParam;
import com.example.sens.vo.UserThresholdSaveParam;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ThresholdServiceimpl implements ThresholdService{

    @Resource
    private ThresholdMapper thresholdMapper;
    @Resource
    private UserThresholdMapper userThresholdMapper;
    @Resource
    private UserQuizMapper userQuizMapper;
    @Resource
    private ConclusionMapper conclusionMapper;
    @Resource
    private QuizMapper quizMapper;
    @Resource
    private UserMapper userMapper;

    @Override
    public Response<List<ThresholdCustom>> find(ThresholdVo thresholdVo) {
        Response<List<ThresholdCustom>> response = new Response<>();
        List<Threshold> thresholdList = thresholdMapper.findByParam(thresholdVo);

        List<String> typeList = thresholdList.stream().map(p -> p.getType()).collect(Collectors.toList());
        Set<String> typeSet = new HashSet<>(typeList);

        typeList = new ArrayList<>(typeSet);
        List<ThresholdCustom> thresholdCustoms = new ArrayList<>();
        List<String> typeString = new ArrayList<>();
        typeList.stream().forEach(p -> {
            typeString.add(p);
        });
        typeString.forEach(type -> {
            ThresholdCustom thresholdCustom = new ThresholdCustom();
            thresholdCustom.setType(type);
            List<Threshold> thresholdList1 = thresholdList.stream().filter(p -> p.getType().equals(type)).collect(Collectors.toList());
            thresholdCustom.setThresholdList(thresholdList1);
            thresholdCustoms.add(thresholdCustom);
        });
        response.setData(thresholdCustoms);
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response save(UserThresholdSaveParam param,HttpSession session) throws Exception {
        Response response = new Response<>();


        List<UserThresholdSaveCustomParam> userThresholdSaveCustomParamList = param.getUserThresholdSaveCustomParamList();
        userThresholdSaveCustomParamList.stream().forEach(t -> {
            List<UserThreshold> userThresholdSaveParamList = t.getUserThresholdList();
            userThresholdSaveParamList.stream().forEach(userThreshold -> {
                userThreshold.setId(UUIDUtil.nextId());
                userThreshold.setType(t.getType());
            });
        });

        ThresholdVo thresholdVo = new ThresholdVo();
        List<Threshold> thresholdList = thresholdMapper.findByParam(thresholdVo);
        UserThresholdSaveParam userThresholdSaveParam = new UserThresholdSaveParam();
        final Integer questionCount = 0;
        List<UserThreshold> checkList = new ArrayList<>();

        if("001".equals(param.getQuizType())) {

            // 71条数据
            thresholdList.stream().forEach(t -> {
                // 检查玩的列表
                userThresholdSaveCustomParamList.stream().forEach(p -> {
                        if (p.getType().equals(t.getType())) {
                            // 每一个表（存入列表）
                            // 填写答案
                            List<UserThreshold> userThresholdList = p.getUserThresholdList();
                            int correntCount = 0;
                            // 正确答案
                            List<Threshold> correctList = thresholdList.stream().filter(th -> th.getType().equals(p.getType())).collect(Collectors.toList());
                            if(t.getType().equals("001")) {
                                // (U1)比较（I2）
                                UserThreshold userThreshold = userThresholdList.stream().filter(p1 -> p1.getU1().equals(t.getU1())).findFirst().orElse(new UserThreshold());
                                if(userThreshold.getI2() != null && Math.abs(userThreshold.getI2()) < t.getImax() && Math.abs(userThreshold.getI2()) > t.getImin()) {
                                    userThreshold.setIsCorrect(true);
                                }
                                checkList.add(userThreshold);
                            }else if(t.getType().equals("002")) {
                                UserThreshold userThreshold = userThresholdList.stream().filter(p1 -> p1.getR().equals(t.getR())).findFirst().orElse(new UserThreshold());
                                if(userThreshold.getI2()!= null && Math.abs(userThreshold.getI2()) < t.getImax() && Math.abs(userThreshold.getI2()) > t.getImin()) {
                                    userThreshold.setIsCorrect(true);
                                }
                                checkList.add(userThreshold);
                            }else if(t.getType().equals("003")) {
                                // (I1) 比较（U2）
                                UserThreshold userThreshold = userThresholdList.stream().filter(p1 -> p1.getI1().equals(t.getI())).findFirst().orElse(new UserThreshold());
                                if(userThreshold.getU2() != null && Math.abs(userThreshold.getU2()) < t.getU2max() && Math.abs(userThreshold.getU2()) > t.getU2min()) {
                                    userThreshold.setIsCorrect(true);
                                }
                            }else if(t.getType().equals("004")) {
                                // (R) 比较（U2）
                                UserThreshold userThreshold = userThresholdList.stream().filter(p1 -> p1.getR().equals(t.getR())).findFirst().orElse(new UserThreshold());
                                if( userThreshold.getU2()!= null && Math.abs(userThreshold.getU2()) < t.getU2max() && Math.abs(userThreshold.getU2()) > t.getU2max()) {
                                    userThreshold.setIsCorrect(true);
                                }
                                checkList.add(userThreshold);
                            }else if(t.getType().equals("005")) {
                                // (U1) 比较（U2）
                                UserThreshold userThreshold = userThresholdList.stream().filter(p1 -> p1.getU1().equals(t.getU1())).findFirst().orElse(new UserThreshold());
                                if(userThreshold.getU2() != null && Math.abs(userThreshold.getU2()) < t.getU2max() && Math.abs(userThreshold.getU2()) > t.getU2max()) {
                                    userThreshold.setIsCorrect(true);
                                }
                                checkList.add(userThreshold);
                            }else if(t.getType().equals("006")) {
                                // (R1) 比较（U2）
                                UserThreshold userThreshold = userThresholdList.stream().filter(p1 -> p1.getR1().equals(t.getR())).findFirst().orElse(new UserThreshold());
                                if(userThreshold.getU2() != null && t.getU2max()!=null && t.getU2min()!=null && Math.abs(userThreshold.getU2()) < t.getU2max() && Math.abs(userThreshold.getU2()) > t.getU2max()) {
                                    userThreshold.setIsCorrect(true);
                                }
                                checkList.add(userThreshold);
                            }else if(t.getType().equals("007")) {
                                // (I1) 比较（U2）
                                UserThreshold userThreshold = userThresholdList.stream().filter(p1 -> p1.getI1().equals(t.getI())).findFirst().orElse(new UserThreshold());
                                if(userThreshold.getU2() !=null && t.getU2max() != null && t.getU2min() !=null &&Math.abs(userThreshold.getU2()) < t.getU2max() && Math.abs(userThreshold.getU2()) > t.getU2max()) {
                                    userThreshold.setIsCorrect(true);
                                }
                                checkList.add(userThreshold);
                            }else if(t.getType().equals("008")) {
                                // (R1) 比较（I2U1）
                                UserThreshold userThreshold = userThresholdList.stream().filter(p1 -> p1.getR1().equals(t.getR())).findFirst().orElse(new UserThreshold());
                                if(userThreshold.getI2()!=null && t.getImin()!=null && t.getImax()!=null && Math.abs(userThreshold.getI2()) < t.getImax() && Math.abs(userThreshold.getI2()) > t.getImin()) {
                                    userThreshold.setIsCorrect(true);
                                }
                                checkList.add(userThreshold);
                            }
                        }
                });
            });
        }
        if(param.getQuizType().equals("002")) {
            param.getUserThresholdSaveCustomParamList().get(0).getUserThresholdList().stream().forEach(cr -> {
                UserThreshold userThreshold = new UserThreshold();
                BeanUtils.copyProperties(cr,userThreshold);
                checkList.add(userThreshold);
            });
        }
        int effect;
        checkList.stream().forEach(t -> {
            t.setUserQuizId(Long.valueOf(param.getUserQuizId()));
        });
        effect = userThresholdMapper.insertBatch(checkList);

        if(effect != checkList.size()) {
            throw new Exception("插入失败");
        }


        List<UserThreshold> correntList = new ArrayList<>();

        checkList.stream().forEach(p -> {
            if(p.getIsCorrect()) {
                correntList.add(p);
            }
        });

        User user = (User) session.getAttribute("user");
        BigDecimal a1 = new BigDecimal(50);
        BigDecimal a2 = new BigDecimal(checkList.size());
//        new BigDecimal(50/checkList.size()*correntList.size());
        BigDecimal score = a1.divide(a2,2);
        if("002".equals(param.getQuizType())) {
            score = new BigDecimal(0);
            BigDecimal addScore = new BigDecimal(10);
            UserThreshold userThreshold =  checkList.get(checkList.size() - 1);
            if(Math.abs(userThreshold.getUac()) < 0.1) {
                score = score.add(addScore);
            }
            if(Math.abs(userThreshold.getUbd()) < 0.1) {
                score = score.add(addScore);
            }
            if(Math.abs(userThreshold.getUcd()) < 0.1) {
                score = score.add(addScore);
            }
            if(Math.abs(userThreshold.getUce()) < 0.1) {
                score = score.add(addScore);
            }
            if(Math.abs(userThreshold.getUdf()) < 0.1) {
                score = score.add(addScore);
            }
        }
        UserQuiz userQuiz = userQuizMapper.selectByPrimaryKey(Long.valueOf(param.getUserQuizId()));
        if("001".equals(param.getQuizType())) {
            userQuiz.setTotalScore(userQuiz.getTotalScore()+score.intValue()*correntList.size());
        }
        if("002".equals(param.getQuizType())) {
            userQuiz.setTotalScore(userQuiz.getTotalScore()+score.intValue());
        }
        // TODO
//        userQuiz.setId(UUIDUtil.nextId());
//        userQuiz.setUserId(user.getUserId());
//        userQuiz.setQuizId(param.getQuizId());
//        userQuiz.setTotalScore(score);
        effect = userQuizMapper.updateByPrimaryKeySelective(userQuiz);

//        effect = userQuizMapper.insert(userQuiz);

        if(effect != 1) {
            throw new Exception("插入失败");
        }

        Conclusion conclusion = new Conclusion();
        conclusion.setId(UUIDUtil.nextId());
        conclusion.setQuizId(param.getQuizId());
        conclusion.setUserId(user.getUserId());
        conclusion.setAnswer(param.getConclusion());
        effect = conclusionMapper.insert(conclusion);
        if (effect != 1) {
            throw new Exception("插入失败");
        }
        response.setSuccess(true);
        return response;
    }

    @Override
    public Page<List<UserQuiz>> findAll(Page page, Long userId) {

        List<UserQuiz> userQuizList = userQuizMapper.findByUserId(userId);
        List<Long> userQuizIds = userQuizList.stream().map(p -> p.getId()).collect(Collectors.toList());
        List<Long> quizIds = userQuizList.stream().map(p -> p.getQuizId()).collect(Collectors.toList());

        List<UserThreshold> userThresholdList = userThresholdMapper.findByQuizId(userQuizIds);
        List<String> typeList = userThresholdList.stream().map(p -> p.getType()).distinct().collect(Collectors.toList());
        List<Quiz> quizList = quizMapper.selectByQuizIds(quizIds);

        List<UserThresholdCustom> userThresholdCustomList = new ArrayList<>();
        typeList.stream().forEach(t -> {
            UserThresholdCustom userThresholdCustom = new UserThresholdCustom();
            userThresholdCustom.setType(t);
            List<UserThreshold> thresholdList = userThresholdList.stream().filter(p -> t.equals(p.getType())).collect(Collectors.toList());
            userThresholdCustom.setUserThresholdList(thresholdList);
            userThresholdCustom.setUserQuizId(thresholdList.get(0).getUserQuizId());
            userThresholdCustomList.add(userThresholdCustom);
        });

        userQuizList.stream().forEach(t-> {
            List<UserThresholdCustom> userThresholdCustoms = userThresholdCustomList.stream().filter(p -> p.getUserQuizId().equals(t.getId())).collect(Collectors.toList());
            t.setUserThresholdCustomList(userThresholdCustoms);
            Quiz quiz = quizList.stream().filter(p -> p.getId().equals(t.getQuizId())).findFirst().orElse(new Quiz());
            t.setPrimaryId(t.getId().toString());
            t.setQuizTitle(quiz.getTitle());
        });

        return page.setRecords(userQuizList);
    }

    @Override
    public Page<List<UserDataCustom>> findAll(Page page) {
        List<UserQuiz> userQuizList = userQuizMapper.selectAll();
        List<Long> quizIds = userQuizList.stream().map(p -> p.getQuizId()).collect(Collectors.toList());
        List<Quiz> quizList = quizMapper.selectByQuizIds(quizIds);
        List<Long> userIds = userQuizList.stream().map(p -> p.getUserId()).collect(Collectors.toList());
        List<User> userList = userMapper.selectByUserIds(userIds);
        List<UserDataCustom> userDataCustoms = new ArrayList<>();

        List<UserThreshold> userThresholdList = userThresholdMapper.findAll1();
        List<String> typeList = userThresholdList.stream().map(p -> p.getType()).distinct().collect(Collectors.toList());
        Collections.reverse(typeList);

        List<Threshold> thresholdCustomList = thresholdMapper.findAll();

        userThresholdList.stream().forEach(t -> {
            Threshold threshold = thresholdCustomList.stream().filter(p -> p.getType().equals(t.getType())).findFirst().orElse(new Threshold());
            t.setThreshold(threshold);
        });

        List<UserThresholdCustom> userThresholdCustomList = new ArrayList<>();
        typeList.stream().forEach(t -> {
            UserThresholdCustom userThresholdCustom = new UserThresholdCustom();
            userThresholdCustom.setType(t);
            List<UserThreshold> thresholdList = userThresholdList.stream().filter(p -> t.equals(p.getType())).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(thresholdList)) {
                userThresholdCustom.setUserQuizId(thresholdList.get(0).getUserQuizId());
            }
            List<Threshold> thresholdList1 = thresholdCustomList.stream().filter(p -> p.getType().equals(t)).collect(Collectors.toList());
            Collections.reverse(thresholdList);
            userThresholdCustom.setThresholdList(thresholdList1);
            userThresholdCustom.setUserThresholdList(thresholdList);
            userThresholdCustomList.add(userThresholdCustom);
        });



        userQuizList.stream().forEach(t -> {
            UserDataCustom userDataCustom = new UserDataCustom();
            Quiz quiz = quizList.stream().filter(p -> p.getId().equals(t.getQuizId())).findFirst().orElse(new Quiz());
            t.setQuizTitle(quiz.getTitle());
            User user = userList.stream().filter(p -> p.getUserId().equals(t.getUserId())).findFirst().orElse(new User());
            t.setUserName(user.getUserName());
            t.setPrimaryId(t.getId().toString());
            userDataCustom.setUserQuiz(t);
            List<UserThresholdCustom> userThresholdCustoms = userThresholdCustomList.stream().filter(p-> t.getId().equals(p.getUserQuizId())).collect(Collectors.toList());
            userDataCustom.setUserThresholdCustomList(userThresholdCustoms);
            userDataCustoms.add(userDataCustom);
        });

        return page.setRecords(userDataCustoms);
    }
}
